﻿#pragma once
#include "Common.h"


//为了保证全局只有唯⼀的centralcache，这个类被设计成了单例模式
//centralcache  承上启下 居中调度
// 存储结构  哈希桶  映射规则同 threadcache桶的映射规则  因为要和threadcache对接
// 区别在于  这里用的是spanlist spanlist的节点是span span是以页为单位的大块内存 span的空间按所挂桶表示的字节大小划分 划分出来的小块内存挂在span的freelist上
// 同时 span内用usecount来记录这个span分出去的内存块数量  等于0的时候表示整个span空闲
// 申请逻辑 threadcache问centralcache要内存块 对应桶上有非空span就直接给 没有就问pagecache要
// 所以 threadcache那边调用FetchRangeObj()获取一批内存块 FetchRangeObj()内调用getonespan()来在对应桶找非空span 然后拿内存块给threadcache用
// getonespan()内   对应桶上没有非空span能用   问pagecache要  要来一个span  切分内存块  然后返回span
// 释放时 central拿到thread还回来的一批内存块 放回到对应的span上  这个span空闲了  就还给pagecache
//此外 作为线程间共享资源 得互斥访问  所以加锁  这里加的时桶锁  每个桶都有一个锁 访问哪个桶就给哪个桶加锁
class CentralCache
{
public:
	static CentralCache* GetInstance()
	{
		return &_sInst;
	}
	// 获取⼀个⾮空的span
	Span* GetOneSpan(SpanList& list, size_t byte_size);
	// 从中⼼缓存获取⼀定数量的对象给thread cache
	size_t FetchRangeObj(void*& start, void*& end, size_t batchNum, size_t size);
	// 将⼀定数量的对象释放到span跨度
	void ReleaseListToSpans(void* start, size_t byte_size);
private:
	CentralCache(){}
	CentralCache(const CentralCache&) = delete;
	static CentralCache _sInst;
private:
	SpanList _spanlist[NFL];
};
